package thread;

import common.IntervalTimer;
import common.TimeManager;
import common.Utility;

public class ManagedThread implements Runnable 
{
	public ManagedThread()
	{
		isActive     = true;
		isRunning    = false;
		isTickThread = true;
		gameThread   = null;
	}
	
	public GameThread getGameThread()
	{
		return gameThread;
	}
	  
	public boolean isActive()
	{
		return isActive;
	}
	
	public void stop()
	{
		isActive = false;
	}
	
	public void active()
	{
		isActive = true;
	}
	
	public boolean isRunning()
	{
		return isRunning;
	}
	
	public void run() 
	{
		if (gameThread == null)
		{
			assert(false);
			return;
		}
		 
		isRunning = true;
		
		if (isTickThread)
		{
			tickRun();
		}
		else
		{
			simpleRun();
		} 
		
		isRunning = false;
	}
	
	private void simpleRun()
	{ 
		while (isActive())
		{
			long nowInMillis = TimeManager.getInstance().getTimeInMillis();
		
			gameThread.doWork(nowInMillis);
		}
	}
	
	private void tickRun()
	{
		int busyCount = 0;
		IntervalTimer intervalTimer = new IntervalTimer();
		int tickInterval = gameThread.getTickInterval();
		int tickIntervalTemp = tickInterval;
		
		intervalTimer.beginTimer(tickInterval, TimeManager.getInstance().getTimeInMillis());
		
		while (isActive())
		{
			long nowInMillis = TimeManager.getInstance().getTimeInMillis();
			
			gameThread.doWork(nowInMillis);
			
			long timeLeft = intervalTimer.getTimeLeft(TimeManager.getInstance().getTimeInMillis());
			
			if (timeLeft > 0)
			{
				busyCount = 0;
				Utility.sleep(timeLeft);
				
				if ((timeLeft) > 200 && (tickIntervalTemp > 100))
				{
					tickIntervalTemp -= 100;
					if (tickIntervalTemp < tickInterval)
					{
						tickIntervalTemp = tickInterval;
					}
				} 
			}
			else
			{
				busyCount++;
				if (busyCount >= 10)
				{
					busyCount = 0;
					tickIntervalTemp += 100;
					if (tickIntervalTemp >= (tickInterval + 3000))
					{
						tickIntervalTemp = tickInterval + 3000;
					}
				} 
			}
			
			intervalTimer.beginTimer(tickIntervalTemp, TimeManager.getInstance().getTimeInMillis());
		}
	}

	public void setGameThread(GameThread thread)
	{
		gameThread = thread;
	}
	
	public void setTickThread(boolean isTick)
	{
		isTickThread = isTick;
	}
	
	private boolean    isActive;
	private boolean    isRunning;
	private boolean    isTickThread;
	private GameThread gameThread;
}
